#include<iostream>
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<cstdlib>
#include<signal.h>

using namespace std;

volatile int flag=0;
void handler(int sig)
{
    cout<<"changet flag 0 to 1"<<endl;
    flag=1;
}

int main()
{
    signal(2,handler);
    while(!flag);
    cout<<"process quit normal"<<endl;
    return 0;
}
// void printfsigpending(sigset_t* set)
// {
//     int i=0;
//     for(;i<32;i++)
//     {
//         if(sigismember(set,i))
//         {
//             putchar('1');
//         }
//         else
//         {
//             putchar('0');
//         }
//     }
//     //想标准输出设备输出字符串并且换行
//     puts("");
// }
// int main()
// {
//     sigset_t s,p;
//     sigemptyset(&s);
//     sigaddset(&s,2);
//     sigprocmask(SIG_BLOCK,&s,nullptr);
//     while(true)
//     {
//         sigpending(&p);
//         printfsigpending(&p);
//         sleep(1);
//     }
//     return 0;
// }
// void printfsigset(sigset_t* set)
// {
//     int i=0;
//     for(;i<32;i++)
//     {
//         if(sigismember(set,i))
//         {
//             putchar('1');
//         }
//         else
//         {
//             putchar('0');
//         }
//     }
//     puts("");
// }
// int main()
// {
//     sigset_t s,p;
//     //初始化信号集
//     sigemptyset(&s);
//     //在信号集当中添加2号有效信号
//     sigaddset(&s,SIGINT);
//     //修改信号屏蔽字的
//     sigprocmask(SIG_BLOCK,&s,nullptr);
//     while(true)
//     {
//         //读取当前进程的未决信号集
//         sigpending(&p);
//         //只有先读取才能打印
//         printfsigset(&p);
//         sleep(1);
//     }
//     return 0;
// }
// void printfsigset(sigset_t* set)
// {
//     int i=0;
//     for(;i<32;i++)
//     {
//         if(sigismember(set,i))
//         {
//             putchar('1');
//         }
//         else
//         {
//             putchar('0');
//         }
//     }
//     puts("");
// }
// int main()
// {
//     sigset_t s,p;
//     sigemptyset(&s);
//     sigaddset(&s,SIGINT);
//     //更改当前的信号屏蔽字
//     sigprocmask(SIG_BLOCK,&s,nullptr);
//     while(true)
//     {
//         //读取当前进程的未决信号集
//         sigpending(&p);
//         //打印当前进程的未决信号集
//         printfsigset(&p);
//         sleep(1);
//     }
//     return 0;
// }
/*
sigset_t 从上图来看，每个信号只有一个bit的未决状态，非0即1，不记录
该信号产生了多少次，阻塞和未决标志都可以用数据类型sigset_t 来
表示，sigset_t 被称为信号集，这个类型可以表示每个信号的有效
或者无效状态，在阻塞信号集当中有效和无效的含义是该信号是否被阻塞
信号集操作函数：
在使用sigset_t类型的变量之前一定要调用初始化函数，使得信号集
处于确定的状态，初始化变量之后就可以对信号集里面的信号位进行、
增加删除等修改操作，
这些函数都是成功的话就返回0，失败的话就返回-1，

==========================================
=================sigpromask //信号屏蔽字====================
==========================================
======================sigpending //未决信号集

==========================================
sigpromask()调用函数sigpromask()可以读取或更改进程的信号屏蔽字
int sigpromask可以读取或者更改进程的信号屏蔽字(阻塞信号集)
int sigpromask(int how,const sigset_t* set,sigset_t* oset);
若是成功则返回0，失败的话则返回-1
==========================================
实际执行信号的处理动作被称为递达，信号从产生到递达之间的状态
被称为信号的未决，进程可以选择阻塞某一个信号，被阻塞的信号产生
时将保持在未决状态，知道进程解除对此信号的阻塞，才执行递达，注意
阻塞和忽略是不同的，只要信号被阻塞就不会被递达，而忽略是在递达
之后的
*/
//模拟野指针异常
// void handler(int sig)
// {
//     cout<<"catch a sig:"<<sig<<endl;
//     sleep(1);
// }
// int main()
// {
//     //当段错误的信号发出以后就会被不断地捕捉
//     signal(SIGSEGV,handler);
//     //这里只能是注册一个方法但是并不一定会被立即执行
//     sleep(1);
//     int* p=nullptr;
//     *p=10;
//     while(true)
//     {}
//     return 0;
// }
// void handler(int sig)
// {
//     cout<<"catch a sig:"<<sig<<endl;
// }
// int main()
// {
//     //信号值，后面再跟一个回调函数
//     //这个时候2号信号就被自定义称为回调函数所描述的动作
//     signal(2,handler);
//     while(true)
//     {}

//     return 0;
// }
// void handler(int sig)
// {
//     cout<<"catch a sig:"<<sig<<endl;
// }
// int main()
// {
//     signal(2,handler);
//     while(true)
//     {

//     }
//     return 0;
// }
/*
产生信号:
1.通过终端按键来产生信号\./
2.调用系统函数来产生信号/.\
signal(pid_t id,int signo);
int raise(int signo);
成功都是返回0，失败返回-1

abort函数使得当前进程收到信号异常终止
由软件条件产生信号
unsigned int alarm(unsigned int seconds);
调用alarm函数就是设定一个闹钟，也就是告诉内核再seconds秒之后
给当前进程发送sigalarm信号，该信号的默认处理方式是终止进程

//初识信号捕捉
*/